/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pl.tom.social.fetcher.jade;

import jade.core.Profile;
import jade.core.ProfileImpl;
import jade.lang.acl.ACLMessage;
import jade.wrapper.AgentController;
import jade.wrapper.AgentState;
import jade.wrapper.ControllerException;
import jade.wrapper.StaleProxyException;
import java.util.ArrayList;
import java.util.List;
import java.util.prefs.Preferences;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.openide.util.NbPreferences;
import pl.tom.social.common.jade.JadeHandler;
import pl.tom.social.fetcher.agent.FetchNodeAgent;
import pl.tom.social.fetcher.agent.FetcherAdminAgent;
import pl.tom.social.fetcher.common.FetcherConsts;
import pl.tom.social.fetcher.gui.FetcherSettingsPanel;

/**
 *
 * @author Tom
 */
public class LocalJade extends JadeHandler {

	private static final Logger logger = Logger.getLogger(LocalJade.class);
	private static LocalJade instance = null;
	private static List<FetchNodeAgent> fetchers = null;

	private LocalJade() {
		fetchers = new ArrayList<FetchNodeAgent>();
	}

	public static synchronized LocalJade getInstance() {
		if (instance == null) {
			instance = new LocalJade();
		}
		return instance;
	}

	public synchronized boolean addFetchNodeAgent(String url) {
		Preferences pref = NbPreferences.forModule(FetcherSettingsPanel.class);
		int maxFetchers = pref.getInt("crawlerMaxFetchers", FetcherConsts.DEFAULT_MAX_FETCHERS);
		if (getFetcherCount() < maxFetchers) {
			try {
				String agentName = getAgentName(url);
				FetchNodeAgent agent = new FetchNodeAgent(url);
				fetchers.add(agent);
				AgentController ac = getContainer().acceptNewAgent(agentName, agent);
				ac.start();
				logger.log(Level.DEBUG, url + " started");
				notifyGlobal(ACLMessage.ACCEPT_PROPOSAL);
				return true;
			} catch (StaleProxyException ex) {
				logger.log(Level.ERROR, null, ex);
			}
		} else {
			notifyGlobal(ACLMessage.REJECT_PROPOSAL);
		}
		return false;
	}

	public synchronized void cancelFetchNodeAgent(String url) {
		try {
			String agentName = getAgentName(url);
			AgentController ac = getContainer().getAgent(agentName);
			//TODO does not seem to stop the agent
			ac.kill();
			logger.log(Level.DEBUG, url + " killed");
		} catch (ControllerException ex) {
			logger.log(Level.ERROR, null, ex);
		}
	}

	private String getAgentName(String base) {
		return base + "-fetch";
	}

	private int getFetcherCount() {
		int count = 0;
		for (int i = 0; i < fetchers.size(); i++) {
			FetchNodeAgent agent = fetchers.get(i);
			if (agent != null && agent.getAgentState().getValue() != AgentState.cAGENT_STATE_DELETED) {
				count++;
			} else {
				logger.log(Level.DEBUG, "\n\nAGENT DELETED " + agent != null ? agent.getName() : "" + "\n\n");
				fetchers.remove(agent);
			}
		}
		logger.log(Level.WARN, "\n\nNUMBER OF RUNNING AGENTS " + count + "\n\n");
		return count;
	}

	@Override
	public synchronized void connectToMainContainer() {
		stopJade();

		logger.log(Level.DEBUG, "Connecting to main container");

		Preferences pref = NbPreferences.forModule(FetcherSettingsPanel.class);
		String mainHost = pref.get("mainHost", "127.0.0.1");
		String mainPort = pref.get("mainPort", "8888");
		Profile pMain = new ProfileImpl();
		pMain.setParameter(Profile.MAIN, "false");
		pMain.setParameter(Profile.MAIN_HOST, mainHost);
		pMain.setParameter(Profile.MAIN_PORT, mainPort);

		jade.core.Runtime rt = jade.core.Runtime.instance();
		container = rt.createAgentContainer(pMain);

		try {
			admin = FetcherAdminAgent.getInstance();
			AgentController ac = container.acceptNewAgent("fetcherAdmin", admin);
			ac.start();
		} catch (StaleProxyException ex) {
			logger.log(Level.ERROR, null, ex);
		}
	}
}
